import { defineStore } from 'pinia'

export const useSocketStore = defineStore(
    'socket',
    {
        state: () => ({
            ws: undefined,
            url: '',
            heartTimeOut: 40000, //监测心跳时间 40秒
            //this.isReConnection = false
            lockReconnect: false, //避免重连
            timerReconnect: undefined,
            timerHeart: undefined,
            timerServerHeart: undefined,
            handClose: false,
            msg: "",
            sendMsgParam: {
                fromId: '',
                toId: '',
                msgContent: '',
                sendTime: null,
                type: 0,
                code: 0,
                status: 0
            }
        }),
        actions: {
            connection(url){
                if("WebSocket" in window){
                    this.url = url
                    this.sendMsgParam.sendTime = new Date()
                    this.sendMsgParam.type = 0
                    this.createWebSocket(url, this.sendMsgParam)
                }
                else{
                    console.log("您的浏览器不支持websocket通信")
                }
            },

            //初始化
            createWebSocket(url, registerMsg){
                try{
                    this.ws = new WebSocket(url)  //
                    this.initWebsocket(registerMsg)
                }
                catch(e){
                    console.log("catch err", e)
                    this.reConnection()
                }
            },

            //建立连接
            initWebsocket(registerMsg){
                this.ws.onopen = (e)=>{
                    //webSocket业务订阅——可以有多个业务
                    this.ws.send(JSON.stringify(registerMsg));
                    console.log("连接成功")
                    //连接成功后，需要开启监测心跳
                    this.heartCheck()
                }

                this.ws.onmessage = (messages)=>{
                    let msg = messages.data
                    if(msg.includes("{")){
                        msg = JSON.parse(msg)
                        if(msg.code === 1001){
                            this.reConnection(this.url)
                        }
                    }
                    this.msg = msg

                    //接收到消息后，需要开启监测心跳
                    this.heartCheck()
                }


                this.ws.onerror = (e)=>{       //连不上时onerror 和 onclose 监听同时会捕捉到
                    console.log("连接失败")
                    // 连失败需要重连
                    this.reConnection()
                }

                this.ws.onclose = (e)=>{
                    console.log("关闭连接")

                    //是否正常关闭  正常关闭不需要重连， 否则需要重连
                    if(!this.handClose){
                        this.reConnection()
                    }
                }
            },

            clearTimer(){
                this.timerReconnect && clearTimeout(this.timerReconnect)
                this.timerHeart && clearTimeout(this.timerHeart)
                this.timerServerHeart && clearTimeout(this.timerServerHeart)
            },

            //重连
            reConnection(){
                console.log("重新连接")
                if(this.lockReconnect){
                    return
                }
                this.lockReconnect = true
                if(this.timerReconnect) {
                    clearTimeout(this.timerReconnect)
                }

                //没连上会一直重连， 设置迟延，避免请求过多
                this.timerReconnect = setTimeout(() => { //setTimeout 到点了执行
                    this.connection(this.url)
                    this.lockReconnect = false
                }, 5000);

            },


            //心跳
            heartCheck(){
                console.log("监测心跳")
                if(this.timerHeart){
                    clearTimeout(this.timerHeart)
                }
                this.timerHeart = setTimeout(() => {
                    console.log("ping");
                    this.ws.send("ping");
                    this.lockReconnect = false
                }, this.heartTimeOut); //40秒

            },

            //发送消息
            sendMsg(){
                if( typeof this.ws !== 'undefined' &&
                    typeof this.ws.readyState !== "undefined" &&
                    this.ws.readyState === WebSocket.OPEN){
                    this.sendMsgParam.sendTime = new Date()
                    this.ws.send(JSON.stringify(this.sendMsgParam))
                }
            },

            //关闭连接 手动关闭
            closeWs(){
                console.log("手动关闭ws")
                this.handClose = true
                this.clearTimer()
                this.ws.close()
            }
        }
    })

export default {useSocketStore}